package com.zb.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zb.entity.ZjCodePrintTemplateComponent;
import com.zb.entity.ZjCodePrintTemplateComponentDataType;
import com.zb.extend.CodePrintTemplateComponentExtend;
import com.zb.mapper.ZjCodePrintTemplateComponentMapper;
import com.zb.service.ZjCodePrintTemplateComponentDataTypeService;
import com.zb.service.ZjCodePrintTemplateComponentService;
import com.zb.vo.CodePrintTemplateComponentChildVo;
import com.zb.vo.CodePrintTemplateComponentDataTypeVo;
import com.zb.vo.CodePrintTemplateComponentVo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 编码打印模板组件表 服务实现类
 * </p>
 *
 * @author WEN
 * @since 2023-09-07
 */
@Service
public class ZjCodePrintTemplateComponentServiceImpl extends ServiceImpl<ZjCodePrintTemplateComponentMapper, ZjCodePrintTemplateComponent> implements ZjCodePrintTemplateComponentService {
    @Resource
    private ZjCodePrintTemplateComponentDataTypeService codePrintTemplateComponentDataTypeService;

    // 保存、修改、删除组件
    @Override
    public void save(Long custAccId, Long printTemplateId, List<CodePrintTemplateComponentVo> templateComponentVos, List<Long> delTemplateComponentIds) {
        if (null != delTemplateComponentIds && !delTemplateComponentIds.isEmpty()) {
            this.removeByIds(delTemplateComponentIds);
        }
        if (null == templateComponentVos || templateComponentVos.isEmpty()) {
            return;
        }
        List<ZjCodePrintTemplateComponent> adds = new ArrayList<>();
        List<ZjCodePrintTemplateComponent> updates = new ArrayList<>();
        ZjCodePrintTemplateComponent component = null;
        ZjCodePrintTemplateComponent componentChild = null;
        List<ZjCodePrintTemplateComponentDataType> addDataTypes = new ArrayList<>();
        List<ZjCodePrintTemplateComponentDataType> updateDataTypes = new ArrayList<>();
        ZjCodePrintTemplateComponentDataType dataType = null;
        List<Long> delDataTypeIds = new ArrayList<>();
        for (CodePrintTemplateComponentVo vo : templateComponentVos) {
            component = new CodePrintTemplateComponentExtend(vo.getId(), custAccId, printTemplateId, vo.getType(), vo.getName());
            // 修改
            if (null != component.getId()) {
                updates.add(component);
                for (CodePrintTemplateComponentChildVo childVo : vo.getComponents()) {
                    componentChild = new ZjCodePrintTemplateComponent();
                    BeanUtils.copyProperties(childVo, componentChild);
                    if (null != componentChild.getId()) {
                        updates.add(componentChild);
                    } else {
                        componentChild.setId(IdWorker.getId());
                        componentChild.setCustAccId(custAccId);
                        componentChild.setPrintTemplateId(printTemplateId);
                        componentChild.setParentId(component.getId());
                        componentChild.setTextColor(null == componentChild.getTextColor()? "" : component.getTextColor());
                        componentChild.setImage(null == componentChild.getImage()? "" : componentChild.getImage());
                        adds.add(componentChild);
                    }
                    if (null != childVo.getDataTypeVos() && !childVo.getDataTypeVos().isEmpty()) {
                        for (CodePrintTemplateComponentDataTypeVo dataTypeVo : childVo.getDataTypeVos()) {
                            dataType = new ZjCodePrintTemplateComponentDataType();
                            BeanUtils.copyProperties(dataTypeVo, dataType);
                            if (null != dataType.getId()) {
                                updateDataTypes.add(dataType);
                                continue;
                            }
                            dataType.setId(IdWorker.getId());
                            dataType.setCustAccId(custAccId);
                            dataType.setPrintTemplateComponentId(componentChild.getId());
                            addDataTypes.add(dataType);
                        }
                    }
                    if (null != childVo.getDelDataTypeIds() && !childVo.getDelDataTypeIds().isEmpty()) {
                        delDataTypeIds.addAll(childVo.getDelDataTypeIds());
                    }
                }
            } else {
                // 新增
                component.setId(IdWorker.getId());
                adds.add(component);
                for (CodePrintTemplateComponentChildVo childVo : vo.getComponents()) {
                    componentChild = new ZjCodePrintTemplateComponent();
                    BeanUtils.copyProperties(childVo, componentChild);
                    componentChild.setId(IdWorker.getId());
                    componentChild.setCustAccId(custAccId);
                    componentChild.setPrintTemplateId(printTemplateId);
                    componentChild.setParentId(component.getId());
                    componentChild.setTextColor(null == componentChild.getTextColor()? "" : component.getTextColor());
                    componentChild.setImage(null == componentChild.getImage()? "" : componentChild.getImage());
                    adds.add(componentChild);
                    if (null != childVo.getDataTypeVos() && !childVo.getDataTypeVos().isEmpty()) {
                        for (CodePrintTemplateComponentDataTypeVo dataTypeVo : childVo.getDataTypeVos()) {
                            dataType = new ZjCodePrintTemplateComponentDataType();
                            BeanUtils.copyProperties(dataTypeVo, dataType);
                            dataType.setId(IdWorker.getId());
                            dataType.setCustAccId(custAccId);
                            dataType.setPrintTemplateComponentId(componentChild.getId());
                            addDataTypes.add(dataType);
                        }
                    }
                }
            }
        }
        if (!adds.isEmpty()) this.saveBatch(adds);
        if (!updates.isEmpty()) this.updateBatchById(updates);
        if (!addDataTypes.isEmpty()) {
            codePrintTemplateComponentDataTypeService.saveBatch(addDataTypes);
        }
        if (!updateDataTypes.isEmpty()) {
            codePrintTemplateComponentDataTypeService.updateBatchById(updateDataTypes);
        }
    }

    // 根据打印模板ID获取模板组件信息
    @Override
    public List<CodePrintTemplateComponentVo> getByPrintTemplateId(Long printTemplateId) {
        QueryWrapper<ZjCodePrintTemplateComponent> wrapper = new QueryWrapper<>();
        wrapper.eq("print_template_id", printTemplateId);
        List<ZjCodePrintTemplateComponent> templateComponents = this.list(wrapper);
        List<Long> ids = templateComponents.stream().map(ZjCodePrintTemplateComponent::getId).toList();
        List<ZjCodePrintTemplateComponentDataType> dataTypes = codePrintTemplateComponentDataTypeService.getByPrintTemplateComponentIds(ids);

        List<CodePrintTemplateComponentVo> componentVoList = templateComponents.stream().filter(t -> 0 == t.getParentId()).map(component -> {
            CodePrintTemplateComponentVo vo = new CodePrintTemplateComponentVo();
            vo.setId(component.getId());
            vo.setType(component.getType());
            vo.setName(component.getName());
            vo.setComponents(templateComponents.stream().filter(k -> Objects.equals(vo.getId(), k.getParentId())).map(ko -> {
                CodePrintTemplateComponentChildVo childVo = new CodePrintTemplateComponentChildVo();
                BeanUtils.copyProperties(ko, childVo);
                if (!dataTypes.isEmpty()) {
                    childVo.setDataTypeVos(dataTypes.stream().filter(dt -> Objects.equals(dt.getPrintTemplateComponentId(), ko.getId())).map(dat -> {
                        CodePrintTemplateComponentDataTypeVo dataTypeVo = new CodePrintTemplateComponentDataTypeVo();
                        BeanUtils.copyProperties(dat, dataTypeVo);
                        return dataTypeVo;
                    }).toList());
                }
                return childVo;
            }).toList());
            return vo;
        }).toList();
        return componentVoList;
    }

    // 根据打印模板ID删除
    @Override
    public void deleteByPrintTemplateIds(List<Long> printTemplateIds) {
        if (null == printTemplateIds || printTemplateIds.isEmpty()) {
            return;
        }
        QueryWrapper<ZjCodePrintTemplateComponent> wrapper = new QueryWrapper<>();
        wrapper.select("id");
        wrapper.in("print_template_id", printTemplateIds);
        List<ZjCodePrintTemplateComponent> components = this.list(wrapper);

        List<Long> ids = components.stream().map(ZjCodePrintTemplateComponent::getId).toList();
        codePrintTemplateComponentDataTypeService.deleteByPrintTemplateComponentIds(ids);
        this.removeByIds(ids);
    }
}
